package com.yupi.springbootinit.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.annotation.OperationLog;
import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.DeleteRequest;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.model.dto.processsheet.*;
import com.yupi.springbootinit.model.entity.Attachment;
import com.yupi.springbootinit.model.entity.ProcessSheet;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.model.vo.ProcessSheetVO;
import com.yupi.springbootinit.model.vo.WorkflowTaskVO;
import com.yupi.springbootinit.service.AttachmentService;
import com.yupi.springbootinit.service.ProcessSheetService;
import com.yupi.springbootinit.service.UserService;
import com.yupi.springbootinit.service.WorkflowTaskService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;

/**
 * 工艺单接口
 */
@RestController
@RequestMapping("/processSheet")
@Slf4j
public class ProcessSheetController {

    @Resource
    private ProcessSheetService processSheetService;

    @Resource
    private UserService userService;

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private WorkflowTaskService workflowTaskService;

    /**
     * ⚠️ 已废弃：直接创建工艺单（不推荐使用）
     * 建议：统一使用 addByTask 方法
     */
    @Deprecated
    @PostMapping("/add")
    public BaseResponse<String> add(@RequestBody ProcessSheetAddRequest request, HttpServletRequest httpRequest) {
        log.warn("⚠️ 使用了已废弃的 /add 接口，建议使用 /addByTask");

        User loginUser = userService.getLoginUser(httpRequest);

        // 仅限管理员使用
        if (!userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "该接口仅限管理员使用，请通过任务列表创建工艺单");
        }

        Long id = processSheetService.createWithSteps(
                request,
                loginUser.getId(),
                loginUser.getUserName(),
                loginUser.getDepartmentId()
        );

        // 返回 String 类型 ID
        return ResultUtils.success(String.valueOf(id));
    }

    /**
     * 基于任务创建工艺单（用于工艺单管理页面从任务列表创建）
     */
    @PostMapping("/addByTask")
    public BaseResponse<String> addByTask(@RequestBody ProcessSheetAddByTaskRequest request,
                                          HttpServletRequest httpRequest) {
        if (request == null || StringUtils.isBlank(request.getTaskId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        }

        User loginUser = userService.getLoginUser(httpRequest);

        // 构建工艺单创建请求
        ProcessSheetAddRequest addRequest = new ProcessSheetAddRequest();
        BeanUtils.copyProperties(request, addRequest);

        // 调用 Service 完成整个流程
        Long sheetId = processSheetService.createProcessSheetFromTask(
                request.getTaskId(),
                addRequest,
                loginUser
        );

        log.info("基于任务创建工艺单成功: taskId={}, sheetId={}, creator={}",
                request.getTaskId(), sheetId, loginUser.getUserName());

        // 返回 String 类型 ID
        return ResultUtils.success(String.valueOf(sheetId));
    }

    /**
     * 删除工艺单
     */
    @PostMapping("/delete")
    @OperationLog(operation = "删除", module = "工艺单")
    public BaseResponse<Boolean> deleteProcessSheet(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();

        // 判断是否存在
        ProcessSheet oldProcessSheet = processSheetService.getById(id);
        ThrowUtils.throwIf(oldProcessSheet == null, ErrorCode.NOT_FOUND_ERROR);

        // 检查权限：只有创建人或管理员可以删除
        User loginUser = userService.getLoginUser(request);
        if (!oldProcessSheet.getCreatedBy().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }

        boolean result = processSheetService.removeById(id);
        return ResultUtils.success(result);
    }

    /**
     * 更新工艺单（含明细）
     */
    @PostMapping("/update")
    @OperationLog(operation = "修改", module = "工艺单")
    public BaseResponse<Boolean> updateProcessSheet(@RequestBody ProcessSheetUpdateRequest processSheetUpdateRequest, HttpServletRequest request) {
        if (processSheetUpdateRequest == null || StringUtils.isBlank(processSheetUpdateRequest.getId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long id = Long.parseLong(processSheetUpdateRequest.getId());

        // 判断是否存在
        ProcessSheet oldProcessSheet = processSheetService.getById(id);
        ThrowUtils.throwIf(oldProcessSheet == null, ErrorCode.NOT_FOUND_ERROR);

        User loginUser = userService.getLoginUser(request);

        boolean result = processSheetService.updateWithSteps(processSheetUpdateRequest, loginUser.getId(), loginUser.getUserName());
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取工艺单详情
     */
    @GetMapping("/get")
    public BaseResponse<ProcessSheetVO> getProcessSheetVOById(@RequestParam String id, HttpServletRequest request) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long idLong;
        try {
            idLong = Long.parseLong(id);
        } catch (NumberFormatException e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "ID格式错误");
        }

        ProcessSheet processSheet = processSheetService.getById(idLong);
        if (processSheet == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return ResultUtils.success(processSheetService.getProcessSheetVO(processSheet));
    }

    /**
     * 分页获取工艺单列表（管理员）
     */
    @PostMapping("/list/page")
    @OperationLog(operation = "查询", module = "工艺单")
    public BaseResponse<Page<ProcessSheetVO>> listProcessSheetByPage(@RequestBody(required = false) ProcessSheetQueryRequest processSheetQueryRequest) {
        if (processSheetQueryRequest == null) {
            processSheetQueryRequest = new ProcessSheetQueryRequest();
        }
        long current = processSheetQueryRequest.getCurrent() > 0 ? processSheetQueryRequest.getCurrent() : 1;
        long size = processSheetQueryRequest.getPageSize() > 0 ? processSheetQueryRequest.getPageSize() : 10;
        Page<ProcessSheet> processSheetPage = processSheetService.page(new Page<>(current, size),
                processSheetService.getQueryWrapper(processSheetQueryRequest));
        return ResultUtils.success(processSheetService.getProcessSheetVOPage(processSheetPage));
    }

    /**
     * 解析工艺卡 Excel（multipart 上传，不落库）
     */
    @PostMapping(value = "/parseExcel")
    @OperationLog(operation = "解析Excel", module = "工艺单")
    public BaseResponse<List<ProcessSheetExcelStepDTO>> parseExcel(@RequestParam("file") MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件不能为空");
        }
        List<ProcessSheetExcelStepDTO> steps = processSheetService.parseProcessSheetExcel(file);
        return ResultUtils.success(steps);
    }

    /**
     * 解析工艺卡 Excel（按附件ID，不需要 multipart）
     */
    @PostMapping("/parseExcelByAttachment")
    @OperationLog(operation = "解析Excel(附件)", module = "工艺单")
    public BaseResponse<List<ProcessSheetExcelStepDTO>> parseExcelByAttachment(@RequestParam("attachmentId") String attachmentId) {
        if (StringUtils.isBlank(attachmentId)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "attachmentId 不能为空");
        }

        Long attachmentIdLong;
        try {
            attachmentIdLong = Long.parseLong(attachmentId);
        } catch (NumberFormatException e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "attachmentId 格式错误");
        }

        Attachment attachment = attachmentService.getById(attachmentIdLong);
        if (attachment == null || attachment.getIsDelete() != null && attachment.getIsDelete() == 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "附件不存在");
        }
        File diskFile = new File(attachment.getFilePath());
        if (!diskFile.exists()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "文件不存在或已被清理");
        }
        List<ProcessSheetExcelStepDTO> steps = processSheetService.parseProcessSheetExcel(diskFile, attachment.getFileName());
        return ResultUtils.success(steps);
    }

    /**
     * 查询当前用户已认领的创建工艺单任务列表
     */
    @PostMapping("/myTasks")
    @OperationLog(operation = "查询", module = "工艺单任务")
    public BaseResponse<Page<WorkflowTaskVO>> listMyProcessSheetTasks(@RequestBody(required = false) ProcessSheetTaskQueryRequest req, HttpServletRequest request) {
        if (req == null) {
            req = new ProcessSheetTaskQueryRequest();
        }
        long current = req.getCurrent() == null ? 1L : req.getCurrent();
        long size = req.getPageSize() == null ? 10L : req.getPageSize();
        if (size > 50) {
            size = 50;
        }
        String status = req.getStatus();

        User loginUser = userService.getLoginUser(request);
        Page<WorkflowTaskVO> page = workflowTaskService.pageMyProcessSheetTasks(loginUser.getId(), status, current, size, loginUser);
        return ResultUtils.success(page);
    }

    /**
     * 查询创建工艺单任务列表（支持管理员查看所有任务）
     */
    @PostMapping("/tasks")
    @OperationLog(operation = "查询", module = "工艺单任务")
    public BaseResponse<Page<WorkflowTaskVO>> listProcessSheetTasks(@RequestBody(required = false) ProcessSheetTaskAdminQueryRequest req, HttpServletRequest request) {
        if (req == null) {
            req = new ProcessSheetTaskAdminQueryRequest();
        }
        long current = req.getCurrent() == null ? 1L : req.getCurrent();
        long size = req.getPageSize() == null ? 10L : req.getPageSize();
        if (size > 50) {
            size = 50;
        }
        String status = req.getStatus();
        Long targetUserId = req.getUserId();

        User loginUser = userService.getLoginUser(request);
        boolean isAdmin = userService.isAdmin(loginUser);

        // 非管理员只能查看自己的任务
        if (!isAdmin) {
            targetUserId = loginUser.getId();
        }

        Page<WorkflowTaskVO> page = workflowTaskService.pageProcessSheetTasks(targetUserId, isAdmin, status, current, size, loginUser);
        return ResultUtils.success(page);
    }

    /**
     * 根据订单ID获取工艺单ID
     * @param orderId 订单ID（String类型）
     * @param sourceType 来源类型（1-销售订单，2-研发订单，默认1）
     * @return 工艺单ID（String类型）
     */
    @GetMapping("/getIdByOrderId")
    public BaseResponse<String> getProcessSheetIdByOrderId(
            @RequestParam String orderId,
            @RequestParam(defaultValue = "1") Integer sourceType) {

        if (StringUtils.isBlank(orderId)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单ID不能为空");
        }

        Long orderIdLong;
        try {
            orderIdLong = Long.parseLong(orderId);
        } catch (NumberFormatException e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单ID格式错误");
        }

        Long processSheetId = processSheetService.getProcessSheetIdByOrderId(orderIdLong, sourceType);

        if (processSheetId == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "该订单未关联工艺单");
        }

        // 返回 String 类型 ID
        return ResultUtils.success(String.valueOf(processSheetId));
    }
}